package com.gimi.cloud.jimi.client.controller.userInfo;

import com.gimi.cloud.jimi.client.service.UserService;
import com.gimi.cloud.jimi.client.service.bank.BankService;
import com.gimi.cloud.jimi.client.service.core.TongDunService;
import com.gimi.cloud.jimi.client.service.userInfo.UserInfoService;
import com.gimi.cloud.jimi.common.enums.ResponseCodeEnum;
import com.gimi.cloud.jimi.common.exception.MsgException;
import com.gimi.cloud.jimi.common.utils.*;
import com.gimi.cloud.jimi.common.utils.oss.AliOSSUtil;
import com.gimi.cloud.jimi.common.utils.reqhead.Response;
import com.gimi.cloud.jimi.common.utils.reqhead.Util;
import com.gimi.cloud.jimi.dao.dao.sys.SysConfigDao;
import com.gimi.cloud.jimi.dto.bank.BankCardDTO;
import com.gimi.cloud.jimi.dto.core.TongDunDTO;
import com.gimi.cloud.jimi.dto.lianlian.PayCashDTO;
import com.gimi.cloud.jimi.dto.userInfo.RdUserInfoDTO;

import com.gimi.cloud.jimi.entity.bank.BankCard;
import com.gimi.cloud.jimi.entity.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;

/**
 * 用户详细信息管理
 * @author chendi
 * @date 2017年12月27日
 */
@RestController
@RequestMapping(value = "userInfo")
public class UserInfoController {
    private static Logger logger = LoggerFactory.getLogger(UserInfoController.class);
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserService userService;
    @Autowired
    private TongDunService tongDunService;
    @Autowired
    private BankService bankService;
    @Autowired
    private SysConfigDao sysConfigDao;
    
    /**
     * 新添加user详细信息
     * @param userInfoDTO
     * @param response
     */
    @RequestMapping(value = "/add")
    public void addUserInfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
        Response resp = new Response();
        userInfoService.addUserInfo(userInfoDTO);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }   
    /** 
     * 根据user_id查询user详细信息
     */
    @RequestMapping(value = "/single")
    public void single(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
        Response resp = new Response();
        RdUserInfoDTO data = userInfoService.getUserInfoSingle(userInfoDTO);
        resp.setRes_data(data);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }
    /**
     * 更新user信息
     * @param userInfoDTO
     * @param response
     */
    @RequestMapping(value = "/update")
    public void updateUserInfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
        Response resp = new Response();
        userInfoService.updateUserInfo(userInfoDTO);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    /**
     * App端更新user信息
     * @param rdUserInfoDTO
     * @param response
     */
    @RequestMapping(value = "/updateAppUserIdinfo")
    public void updateAppUserIdinfo(@RequestBody RdUserInfoDTO rdUserInfoDTO, HttpServletResponse response) throws Exception {
        logger.info("App端更新user信息，请求参数requestDataMap:" + rdUserInfoDTO);
        Response resp = new Response();
        User userBean = userService.getUserById(rdUserInfoDTO.getUserId());
        //检验user是否存在
        checkUserBean(userBean,response);
        String cardId = rdUserInfoDTO.getCardId();//身份证号

        // 判断身份证是否已经被别人实名用过，必须进行的判断（此时由cardId查出的user_info可能为空）
        RdUserInfoDTO exists = userInfoService.getUserBycardId(cardId);
        if (exists != null) { // 如果存在，且用户id与当前id不一致
            if (userBean.getUserId().intValue() != exists.getUserId().intValue()) {
                resp.setResponseCode(ResponseCodeEnum.ERR_REALNAME_NOT_AUTH);
                Util.sendResponse(JsonUtil.toJson(resp), response);
                return;
            }
        }
        //再查出userId下的rd_user_info
        RdUserInfoDTO userIdinfo = userInfoService.getUserInfoByUserId(userBean.getUserId());

        //将传来的参数dto的值给到从数据库里查到的dto
        rdUserInfoDTO.setCardFront(AliOSSUtil.getFilePath(rdUserInfoDTO.getCardFront()));
        rdUserInfoDTO.setCardBack(AliOSSUtil.getFilePath(rdUserInfoDTO.getCardBack()));
        rdUserInfoDTO.setAvatar(AliOSSUtil.getFilePath(rdUserInfoDTO.getAvatar()));
        MyBeanUtils.copyPropertiesIgnoreNull(rdUserInfoDTO,userIdinfo);

        //TODO 身份证的数据有效期起',数据有效期止',不知道怎么定义，是由产品或者风控定
        userIdinfo.setReportEffectionBegin(DateUtil.getNow());
        userIdinfo.setReportEffectionEnd(DateUtil.getLateYear(1));
        userIdinfo.setUpdateTime(new Date());

        try {
            //首先查出来是否已经拉过同盾，如果在同盾的有效期内，就update，有效期外就insert
            TongDunDTO tongDunDTO = new TongDunDTO();
            tongDunDTO.setId_number(cardId);
            tongDunDTO.setMobile(userIdinfo.getMobilePhone());
            tongDunDTO.setName(userIdinfo.getRealName());
            tongDunDTO.setUserId(userIdinfo.getUserId());
            //同盾增加开关，从sys_config中获取cf_value值：1:开启。0：关闭
            String config = sysConfigDao.getConfigByKey("notBankCard");
            if ("1".equals(config)) {
                tongDunService.getTongDun(tongDunDTO);
            }
        }catch (Exception e){
            logger.info("同盾获取出现问题，userId="+rdUserInfoDTO.getUserId());
        }
        userInfoService.updateUserInfo(userIdinfo);

        // 修改认证状态
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    /**
     * 上传身份证等图片,其中front为身份证正面，back为身份证背面，avatar为身份证小头像，hand为人脸识别的照片
     * @param map
     * @param response
     */
    @RequestMapping(value = "/uploadCardPhoto")
    public void uploadCardPhoto(@RequestParam Map<String,String>map,HttpServletRequest request, HttpServletResponse response) throws Exception {
        Response resp = new Response();
        String url = "";
        StandardMultipartHttpServletRequest multipartHttpServletRequest = (StandardMultipartHttpServletRequest) request;
        MultiValueMap multipartFiles = multipartHttpServletRequest.getMultiFileMap();

        String type = map.get("type");
        String userId = map.get("userId");

        User user = userService.getUserById(Integer.valueOf(userId));
        for(Object entry : multipartFiles.entrySet()){
            LinkedList<MultipartFile> lists = ((Map.Entry<String, LinkedList<MultipartFile>>) entry).getValue();
            for(MultipartFile file : lists){
                InputStream is = file.getInputStream();
                String dirPath = "userInfo/"+user.getMobilePhone();
                String[] originalFilenames = file.getOriginalFilename().split("\\.");
                if(originalFilenames == null || originalFilenames.length < 1){
                    throw new MsgException(ResponseCodeEnum.INVALID,"不支持的文件类型");
                }
                CommonUtil.checkIsImage(originalFilenames[originalFilenames.length-1]);
                String fileName = type + "." + originalFilenames[originalFilenames.length-1];
                String result = AliOSSUtil.uploadFileCanBeOverLoad(is,dirPath,fileName);
                String tempUrl = AliOSSUtil.getFileUrl(result,new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365 * 100l));
                System.out.println("==========>上传结果：" + tempUrl);
                url += ","+tempUrl;
            }
        }

        Map<String,String> data = new HashMap<>();
        data.put("url",url.equals("")?url:url.substring(1));
        resp.setRes_data(data);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    /**
     * 查询user信息
     * @param userInfoDTO
     * @param response
     */
    @RequestMapping(value = "/getUserInfo")
    public void getUserInfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
        logger.info("身份证查询，请求参数requestDataMap:" + userInfoDTO);
        Response resp = new Response();
        User userBean = userService.getUserById(userInfoDTO.getUserId());
        //检验user是否存在
        checkUserBean(userBean,response);
        RdUserInfoDTO userIdinfo = userInfoService.getUserInfoByUserId(userInfoDTO.getUserId());
        resp.setRes_data(userIdinfo);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJSONStringWithDateFormatYYYYMMDDHHMMSS(resp), response);
    }

    /**
     * App端更新bank信息
     * @param bankCardDTO
     * @param response
     */
    @RequestMapping(value = "/updateUserbankcard")
    public void updateUserbankcard(@RequestBody BankCardDTO bankCardDTO, HttpServletResponse response) throws Exception {
        logger.info("银行卡更新，请求参数requestDataMap:" + bankCardDTO);
        Response resp = new Response();
        User userBean = userService.getUserById(bankCardDTO.getUserId());
        //检验user是否存在
        checkUserBean(userBean,response);
        String cardNo = bankCardDTO.getCardNo();//银行卡号

        /** 不支持的银行卡号，主要是邮政的 */
        boolean flag = false;

        String config = sysConfigDao.getConfigByKey("notBankCard");
        logger.info("不支持的银行卡号，请求参数：" + config);

        List<String> notBankCardResults = Arrays.asList(config.split(","));
        // 如果满足在黑名单中的银行卡那么久返回不支持
        for (String string : notBankCardResults) {
            if (cardNo.startsWith(string)) {
                flag = true;
                break;
            }
        }
        if (flag) {
            throw new MsgException(ResponseCodeEnum.BANK_ERROR);
        }

        logger.info("银行卡更新接口.........开始查询连连.........");


        /**-----TODO 此时如果放开此连连查询接口，则会报{"ret_code":"1008","ret_msg":"商户请求IP错误"} , 所以先注释了 */
//        Map<String, String> map = bankService.bankcardQuery(cardNo);
//        if(StringUtil.isBlank(map.get("bank_name"))){
//            throw new MsgException(ResponseCodeEnum.MEMORY_CARD);
//        }
//        String bank_name = map.get("bank_name").replaceAll("\\(|\\)", "");
//        String bank_code = map.get("bank_code");
//        String card_type = map.get("card_type");
//
//        logger.info("银行卡更新接口.........结束查询连连.........");
//        if (!"2".equals(card_type)) {
//            throw new MsgException(ResponseCodeEnum.MEMORY_CARD);
//        }
//        // 判断是否支持该银行
//        boolean useable = bankService.useable(bank_code);
//        if (!useable) {
//            throw new MsgException(ResponseCodeEnum.BANK_ERROR);
//        }

        /**-----TODO 此时如果放开此连连查询接口，则会报{"ret_code":"1008","ret_msg":"商户请求IP错误"} , 所以先注释了 */

        //根据userId找到Bank，没有则新增
        BankCard bank = bankService.getBankByUserId(bankCardDTO.getUserId());
        //判断是去新增还是去修改
        boolean temp = false;
        if(bank==null){
            bank = new BankCard();
            bank.setAddTime(new Date());
            temp = true;
        }else{
            bank.setUpdateTime(new Date());
        }
        MyBeanUtils.copyPropertiesIgnoreNull(bankCardDTO,bank);
        //TODO 所属银行的id待定
        //bank.setBiId();

        if(temp){
            bankService.insert(bank);
        }else{
            bankService.update(bank);
        }
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

    /**
     * App端获得bank信息签约json
     * @param bankCardDTO
     * @param response
     */
    @RequestMapping(value = "/bankCardSign")
    public void bankCardSign(@RequestBody BankCardDTO bankCardDTO, HttpServletResponse response) throws Exception {
        logger.info("银行卡更新，请求参数requestDataMap:" + bankCardDTO);
        Map<String, Object> data = new HashMap<String, Object>();
        Response resp = new Response();
        User userBean = userService.getUserById(bankCardDTO.getUserId());
        //检验user是否存在
        checkUserBean(userBean,response);
        String cardNo = bankCardDTO.getCardNo();//银行卡号

        // 判断银行卡号是否存在
        BankCard exits = bankService.getBankBycardNo(cardNo);
        if (exits != null) { // 如果存在，且用户id与当前id不一致
            if (userBean.getUserId().intValue() != exits.getUserId().intValue()) {
                resp.setResponseCode(ResponseCodeEnum.ERR_BANKNO_NOT_AUTH);
                Util.sendResponse(JsonUtil.toJson(resp), response);
                return;
            }
        }

        RdUserInfoDTO rdUserInfoDTO = userInfoService.getUserInfoByUserId(userBean.getUserId());
        if(rdUserInfoDTO==null){
            resp.setResponseCode(ResponseCodeEnum.ERR_CARDID_NOT_AUTH);
            Util.sendResponse(JsonUtil.toJson(resp), response);
            return;
        }
        //此处进行拼接json
        PayCashDTO result = bankService.bankCardSign(rdUserInfoDTO,cardNo);

        // 修改认证状态
        data.put("reqJson", result);
        resp.setRes_data(data);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }
    /**
     * 查询bank信息
     * @param userInfoDTO
     * @param response
     */
    @RequestMapping(value = "/getUserBankcard")
    public void getUserBankcard(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
        logger.info("查询bank信息，请求参数requestDataMap:" + userInfoDTO);
        Response resp = new Response();
        User userBean = userService.getUserById(userInfoDTO.getUserId());
        //检验user是否存在
        checkUserBean(userBean,response);
        BankCardDTO bank = bankService.getBankDTOByUserId(userInfoDTO.getUserId());
        RdUserInfoDTO infoDTO = userInfoService.getUserInfoByUserId(userInfoDTO.getUserId());
        if(bank!=null && infoDTO != null) {
            //因rd_bank_card表里没有userName字段，所以从rd_user_info表里取该字段
            bank.setUserName(infoDTO.getRealName());
        }
        resp.setRes_data(bank);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
        Util.sendResponse(JsonUtil.toJSONStringWithDateFormatYYYYMMDDHHMMSS(resp), response);
    }

    public void checkUserBean(User user,HttpServletResponse response){
        Response resp = new Response();
        if (user == null) {
            resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
            resp.setRes_msg("用户不存在");
            Util.sendResponse(JsonUtil.toJson(resp), response);
            return;
        }
    }


}
